home *** CD-ROM | disk | FTP | other *** search
- /*
- Present a dialog box with a text rectangle, a scroll bar, and an OK
- button. This can be used as a help dialog. Pass in a dialog
- resource number and a handle to the text. The dialog should
- have the OK button as the first item, and user items for the
- second and third items. The second is the rect in which the
- control is drawn, the third is the rect in which text is drawn.
- Only the OK button should be enabled.
-
- The text handle should be locked before calling TextDlog and
- unlocked after.
-
- Original author: dubois@uwmacc.UUCP (Paul DuBois)
- with a few changes & cleanup by: blob@apple.com (Brian Bechtel)
- */
-
- #include <stdio.h>
- # include <Events.h>
- # include <Dialogs.h>
- # include <Controls.h>
-
- #include "textdlog.h"
- #include "DialogUtils.h"
-
- #define ETX 03 /* Enter key */
- #define CR 13 /* Return key */
-
- #include "TextDlog.proto.h"
-
- enum /* item numbers */
- {
- OKButton = 1,
- scrollBarUser,
- textRectUser
- };
-
- static ControlHandle theScroll;
- static Boolean needScroll; /* true if need scroll bar */
- static short curLine;
- static short halfPage;
- static TEHandle teHand;
-
-
-
- /************************************************************************
- *
- * Function: HighLightDefault
- *
- * Purpose: highlight the default button in a dialog
- *
- * Returns: nothing
- *
- * Side Effects: standard box is drawn around highlight box
- *
- * Description: draws the heavy rounded box around the OK button,
- * so that the user knows that hitting enter or return
- * is the same as pressing the OK button.
- *
- ************************************************************************/
- void
- HighLightDefault(DialogPtr dPtr)
- {
- short unusedItemType;
- Handle unusedItemHandle;
- Rect box;
- PenState p;
- GrafPtr savedPort;
-
- /* This next little piece of code puts the default heavy rounded
- box around the "OK" button, so the user knows that pressing
- return is the same as hitting "OK"
- */
- GetPort(&savedPort);
- SetPort(dPtr); /* without this, can't highlite OK */
- GetDItem(dPtr, OKButton, &unusedItemType, &unusedItemHandle, &box);
- GetPenState(&p);
- PenSize(3,3);
- InsetRect(&box, -4, -4);
- FrameRoundRect(&box, 16, 16);
- PenSize(p.pnSize.h, p.pnSize.v);
- SetPort(savedPort);
- }
-
- /************************************************************************
- *
- * Function: DrawScroll
- *
- * Purpose: draw scroll bar user item
- *
- * Returns: nothing
- *
- * Side Effects: draws scroll bar user item
- *
- * Description: if we need to scroll, show the control.
- *
- ************************************************************************/
- static pascal void DrawScroll (DialogPtr theDialog, short itemNo)
- {
- if (needScroll)
- ShowControl (theScroll);
- }
-
-
- /************************************************************************
- *
- * Function: DrawTextRect
- *
- * Purpose: draw text display user item
- *
- * Returns: nothing
- *
- * Side Effects: shows the text
- *
- * Description: Get the rectangle for our text. If we need to scroll,
- * frame the rectangle so that it will look correct.
- * Get the view rectangle of our text rectangle, and do
- * a TEUpdate so that text edit will properly handle
- * updating the rectangle.
- *
- ************************************************************************/
- static pascal void DrawTextRect (DialogPtr theDialog, short itemNo)
- {
- Rect r;
- short itemType;
- Handle itemHandle;
-
- GetDItem (theDialog, textRectUser, &itemType, &itemHandle, &r);
- if (needScroll)
- FrameRect (&r);
- r = (**teHand).viewRect;
- TEUpdate (&r, teHand);
- }
-
-
- /************************************************************************
- *
- * Function: DoScroll
- *
- * Purpose: scroll to correct position
- *
- * Returns: nothing.
- *
- * Side Effects: text is scrolled to new position
- *
- * Description:
- * Scroll to the correct position. lDelta is the
- * amount to CHANGE the current scroll setting by.
- *
- ************************************************************************/
- static void
- DoScroll (short lDelta)
- {
- short newLine;
-
- newLine = curLine + lDelta;
- if (newLine < 0) newLine = 0;
- if (newLine > GetCtlMax (theScroll)) newLine = GetCtlMax (theScroll);
- SetCtlValue (theScroll, newLine);
- lDelta = (curLine - newLine ) * (**teHand).lineHeight;
- TEScroll (0, lDelta, teHand);
- curLine = newLine;
- }
-
-
-
- /************************************************************************
- *
- * Function:
- *
- * Purpose: track the scrolling
- *
- * Returns: nothing
- *
- * Side Effects: scrolling
- *
- * Description: get the control part that we're in. If we're still
- * in the same part, we're going to scroll. Check what
- * kind of part we're in, and set our delta accordingly.
- * Call DoScroll to actually handle the scrolling.
- *
- ************************************************************************/
- static pascal void __TrackScroll (ControlHandle theScroll, short partCode)
- {
- short lDelta;
-
- if (partCode == GetCRefCon (theScroll)) /* still in same part? */
- {
- switch (partCode)
- {
- case inUpButton: lDelta = -1; break;
- case inDownButton: lDelta = 1; break;
- case inPageUp: lDelta = -halfPage; break;
- case inPageDown: lDelta = halfPage; break;
- }
- DoScroll (lDelta);
- }
- }
-
-
- /************************************************************************
- *
- * Function: TextFilter
- *
- * Purpose: filter to handle hits in scroll bar
- *
- * Returns: false (indicating we should continue within our
- * modal dialog)
- *
- * Side Effects: May scroll the text
- *
- * Description: We're being called as part of a ModalDialog call.
- * Check what kind of event activated us. If it was a
- * mouseDown, handle it. If we were in the thumb, track
- * the thumb, otherwise scroll the indicated amount.
- *
- ************************************************************************/
- static pascal Boolean TextFilter (DialogPtr theDialog, EventRecord *theEvent, short *itemHit)
- {
- Point thePoint;
- short thePart;
- Boolean result;
- static ControlActionUPP gTrack;
-
- gTrack = NewControlActionProc(__TrackScroll);
- result = false;
- switch (theEvent->what)
- {
- case mouseDown:
- thePoint = theEvent->where;
- GlobalToLocal (&thePoint);
- thePart = TestControl (theScroll, thePoint);
- if (thePart == inThumb)
- {
- (void) TrackControl (theScroll, thePoint, nil);
- DoScroll (GetCtlValue (theScroll) - curLine);
- }
- else if (thePart != 0)
- {
- SetCRefCon (theScroll, (long) thePart);
- (void) TrackControl (theScroll, thePoint, gTrack);
- }
- break;
- case keyDown:
- if ((theEvent->message & charCodeMask) == ETX)
- {
- *itemHit = 1;
- result = true;
- }
- if ((theEvent->message & charCodeMask) == CR)
- {
- *itemHit = 1;
- result = true;
- }
- break;
- case updateEvt:
- case activateEvt:
- HighLightDefault(theDialog);
- break;
- }
- DisposeRoutineDescriptor(gTrack);
- return (result);
- }
-
-
-
- /************************************************************************
- *
- * Function: TextDialog
- *
- * Purpose: put up text dialog with optional scroll bar
- *
- * Returns: nothing
- *
- * Side Effects: none
- *
- * Description: Pass in a dialog number, a handle to the text to
- * display, a font number, font size, and a boolean
- * indicating whether you want the text to wrap or not.
- *
- * The dialog referenced by dlogNum should have the
- * OK button as the first item, and user items for the
- * second and third items. The second is the rect in
- * which the control is drawn, the third is the rect in
- * which text is drawn. Only the OK button should be
- * enabled.
- *
- * The text handle should be locked before calling us,
- * and unlocked afterwards.
- *
- * Of course, the font number and size should exist in
- * the current system, or it will default to something
- * ugly.
- *
- ************************************************************************/
- void
- TextDialog (short dlogNum, Handle textHandle, short fontNum, short fontSize, Boolean wrap)
- {
- GrafPtr oldPort;
- DialogPtr theDialog;
- short itemNo;
- short itemType;
- Handle itemHandle;
- Rect r;
- short scrollLines;
- short viewLines;
- Handle oldHText;
- static ModalFilterUPP filterProc;
- static UserItemUPP drawTextProc;
- static UserItemUPP drawScrollProc;
-
- GetPort (&oldPort);
- theDialog = GetNewDialog (DU_CenterDLOG(dlogNum), (DialogPeek)nil, (WindowPtr)-1L);
-
- GetDItem (theDialog, textRectUser, &itemType, &itemHandle, &r);
- drawTextProc = NewUserItemProc(DrawTextRect);
- SetDItem (theDialog, textRectUser, itemType, (Handle)drawTextProc, &r);
- /*
- incorporate text into a TERec.
- */
- SetPort (theDialog);
- TextFont (fontNum);
- TextSize (fontSize);
-
- InsetRect (&r, 4, 4);
- teHand = TENew (&r, &r);
- if (!wrap)
- (**teHand).crOnly = -1;
- oldHText = (**teHand).hText; /* save this. restore later */
- (**teHand).hText = textHandle;
- TECalText (teHand);
- viewLines = (r.bottom - r.top) / (**teHand).lineHeight;
- scrollLines = (**teHand).nLines - viewLines;
- needScroll = (scrollLines > 0);
- GetDItem (theDialog, scrollBarUser, &itemType, &itemHandle, &r);
- drawScrollProc = NewUserItemProc(DrawScroll);
- SetDItem (theDialog, scrollBarUser, itemType, (Handle)drawScrollProc, &r);
- if (needScroll)
- {
- theScroll = NewControl (theDialog, &r, NULL, false, 0, 0, 0,
- scrollBarProc, 0L);
- SetCtlMax (theScroll, scrollLines);
- halfPage = viewLines / 2;
- curLine = 0;
- filterProc = NewModalFilterProc(TextFilter);
- }
-
- ShowWindow (theDialog);
-
- do {
- ModalDialog (filterProc, &itemNo);
- } while (itemNo != OKButton);
-
- /*
- restore hText field of TE record before disposing of it.
- */
- (**teHand).hText = oldHText;
- TEDispose (teHand);
-
- if (needScroll)
- DisposeControl (theScroll);
- SetPort (oldPort);
- DisposeRoutineDescriptor(filterProc);
- DisposeRoutineDescriptor(drawScrollProc);
- DisposeRoutineDescriptor(drawTextProc);
- DisposDialog(theDialog);
- }
-